import sys
import time
import rapidUtils
import createIndex
import c_stemming
import normalizeQuery


morfBases = []
stemming = False

if len(sys.argv) >= 2 and sys.argv[1] == 's':
    stemming = True
    createIndex.loadNode("nodeStaticStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeStem.dat")
    print 'Index ready!'
elif len(sys.argv) >= 2 and  sys.argv[1] == 'n':
    stemming = False
    createIndex.loadNode("nodeStaticNoStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeNoStem.dat")
    print 'Index ready!'
else:    
    stemming = True
    createIndex.loadNode("nodeStaticStem.dat")
    print 'Dictionary ready!'
    createIndex.loadIndex("serializeStem.dat")
    print 'Index ready!'

morfo = open('morfo3.txt')

for line in morfo:
   tokens = line.split()
   temp = []
   for elem in tokens[1:]:
        stemmToken = c_stemming.stemmToken( elem ) 
        if stemmToken is not None:
            number = createIndex.getVal( stemmToken )
            if number > 0 :
                temp.append( number )          
        number = createIndex.getVal( elem )
        if number > 0 :
            temp.append( number )              
   morfBases.append(  temp )
   
print 'Morfo ready!'

morfBases = tuple( morfBases )

wiki = open('titles.txt')

titles = [None]
article = 1

for line in wiki:
    titles.append( line )

titles = tuple(titles)
print 'Titles ready!'
    
print "I'm ready to serve!"

def orPositions(e1,e2):
    if e2[3] == 0:
        return e1
    if e1[3] == 0:
        return e2
    return rapidUtils.orPositions(e1,e2)

def andPositions(e1,e2,n):
    if e2[3] == 0:
        rapidUtils.free(e1)
        return e2
    if e1[3] == 0:
        rapidUtils.free(e2)
        return e1
    return rapidUtils.andPositions(e1,e2,n)

def orArticles(e1,e2):
    return rapidUtils.orArticles(e1,e2)

def andArticles(e1,e2):
    return rapidUtils.andArticles(e1,e2)

def getArticlesFromIndex(n):
    return createIndex.get(n)

def orListPositions(l):
    i = 0
    answer = (0, 0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = orPositions(answer ,elem)
    return answer
    
def andListPositions(l):
    i = 0
    answer = (0, 0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = andPositions(answer ,elem, i)
        i += 1
    return answer
    
def orListArticles(l):
    i = 0
    answer = (0, 0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = orArticles(answer ,elem)
    return answer
        
def andListArticles(l):
    i = 0
    answer = (0, 0, 0, 0, 1)
    for elem in l:
        if i == 0:
            i = 1
            answer = elem
            continue
        answer = andArticles(answer ,elem)
    return answer
    
def getNumbersForWord(word):
    answer = []
    number = createIndex.getVal(word) - 1
    if number < 971575 and number > 0:
        if len( morfBases[number] ) > 0 :
            answer = morfBases[number]

    sToken = c_stemming.stemmToken(word) 
    i = -1
    
    if sToken is not None and stemming:
        i = createIndex.getVal(sToken)
    
    j = createIndex.getVal(word)
    
    if i > 0:
        answer = answer + [i]
    if j > 0:
        answer = answer + [j]
    
    return answer

def getArticlesForWord(word):
    answer = []
    for elem in getNumbersForWord(word):
        answer.append( getArticlesFromIndex(elem) )
    return orListArticles( answer )
            
def getPositionForWord(word):
    answer = []
    for elem in getNumbersForWord(word):
        answer.append( getArticlesFromIndex(elem)  )
    return orListPositions( answer )


def queryPositions(napis):
    napis = normalizeQuery.normalize(napis)
    andQueries = napis.split(" ") 
    answerAnd = []
    for andQuery in andQueries:
        split = andQuery.split("|")
        answerAnd.append( orListPositions( [ getPositionForWord(elem) for elem in split ] ) )

    answer = andListPositions( answerAnd )

    return answer
    
        
def queryArticles(napis):
    napis = normalizeQuery.normalize(napis)
    andQueries = napis.split(" ")
    answerAnd = []
    for andQuery in andQueries:
        split = andQuery.split("|")
        split = [ getArticlesForWord(elem) for elem in split ]
        answerAnd.append( orListArticles( split ) )
    return andListArticles( answerAnd )


def queryAny(line):
    if line[0] == '"':
        return rapidUtils.getArticles( queryPositions(line) )
    else:
        return rapidUtils.getArticles( queryArticles(line) )
        
def test():
    start = time.time()
    i  = 0
    pytania = open('pytania_and_dla_IR.txt')
    odpowiedzi = open('odpowiedzi_na_' + 'pytania_and_dla_IR.txt','w')
    for line in pytania:
      i += 1
      lista = queryAny(line.strip())
      odpowiedzi.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
      for elem in lista:
        if 0 < elem - 1< len(titles):
            odpowiedzi.write( titles[elem ].strip() + '\n')
        else:
            print 'Niespodziewane zachowanie :('
            
    end = time.time()
    print str( i ) + ' queries'
    print str( (end - start) / i ) + ' seconds per query'
    print str( (end - start) ) + ' seconds total'
    

if __name__ == '__main__':
    if len( sys.argv ) >= 3:

        start = time.time()
        i  = 0
        pytania = open(sys.argv[2])
        odpowiedzi = open('odpowiedzi_na_' + sys.argv[2],'w')        
        for line in pytania:
          i += 1
          lista = queryAny(line.strip())
          odpowiedzi.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
          """
          for elem in lista:
            if 0 < elem - 1< len(titles):
                odpowiedzi.write( titles[elem ].strip() + '\n')
          """
        end = time.time()
        print str( (end - start) / i ) + ' seconds per query'
        print str( (end - start) ) + ' seconds total'

    else:
        log = open("log.dat",'w')
        print '! is for quit'
        while True:
            line = raw_input('>')
            if line.strip() == '!':
                break
                log.close()
            start = time.time()
            lista = queryAny(line.strip())
            end = time.time()
            
            log.write( 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista)) + '\n')
            print 'QUERY: ' + line.strip() + ' TOTAL: ' + str(len(lista))
            for elem in lista:
              if 0 < elem - 1< len(titles):
                print titles[elem ].strip() 
                log.write( str(titles[elem ].strip() ) + '\n')

            print str( (end - start) ) + ' seconds per query'        
            log.write( str( (end - start) ) + ' seconds per query\n')
            log.flush()
